from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.core.paginator import Paginator
from django.db.models import Q, Count
from django.http import JsonResponse, HttpResponseForbidden
from django.utils import timezone
from django.views.decorators.http import require_POST
from django.contrib.auth.models import User

from .models import LeaveApplication, LeaveType, Department, UserProfile, LeaveBalance
from .forms import LeaveApplicationForm, UserUpdateForm, UserProfileForm, LeaveFilterForm, CustomUserCreationForm, \
    UserRoleForm, UserSearchForm
from .services import LeaveApprovalService, LeaveBalanceService
from .utils import LeaveStatistics
from .decorators import role_required, supervisor_required, hr_required


@login_required
def dashboard(request):
    """首页仪表板"""
    user = request.user
    current_year = timezone.now().year
    
    # 用户统计数据
    user_applications = LeaveApplication.objects.filter(
        applicant=user,
        start_date__year=current_year
    )
    
    user_stats = {
        'total_applications': user_applications.count(),
        'approved_applications': user_applications.filter(status='approved').count(),
        'total_days': sum(app.days_requested for app in user_applications.filter(status='approved')),
    }
    
    # 最近申请
    recent_applications = LeaveApplication.objects.filter(
        applicant=user
    ).order_by('-created_at')[:5]
    
    # 待审批事项（如果用户有审批权限）
    pending_approvals = []
    if hasattr(user, 'userprofile') and user.userprofile.can_approve_leave():
        pending_approvals = LeaveApprovalService.get_pending_approvals(user)[:5]
    
    context = {
        'user_stats': user_stats,
        'recent_applications': recent_applications,
        'pending_approvals': pending_approvals,
    }
    
    return render(request, 'dashboard.html', context)


@login_required
def apply_leave(request):
    """申请请假"""
    if request.method == 'POST':
        form = LeaveApplicationForm(request.POST, request.FILES)
        if form.is_valid():
            application = form.save(commit=False)
            application.applicant = request.user
            
            # 根据提交的动作决定状态
            action = request.POST.get('action', 'save_draft')
            if action == 'submit':
                application.status = 'draft'  # 先保存为草稿，然后提交
                application.save()
                
                # 提交申请
                try:
                    LeaveApprovalService.submit_application(application, request.user)
                    messages.success(request, '请假申请已成功提交！')
                    return redirect('leave_detail', application.id)
                except Exception as e:
                    messages.error(request, f'提交失败：{str(e)}')
            else:
                # 保存草稿
                application.status = 'draft'
                application.save()
                messages.success(request, '草稿已保存！')
                return redirect('leave_detail', application.id)
    else:
        form = LeaveApplicationForm()
    
    # 获取用户的请假余额
    leave_balances = []
    for leave_type in LeaveType.objects.filter(is_active=True):
        balance = LeaveBalanceService.get_user_balance(request.user, leave_type)
        leave_balances.append(balance)
    
    context = {
        'form': form,
        'leave_balances': leave_balances,
    }
    
    return render(request, 'leaves/apply_leave.html', context)


@login_required
def edit_leave(request, pk):
    """编辑请假申请"""
    application = get_object_or_404(LeaveApplication, pk=pk, applicant=request.user)
    
    if not application.can_be_edited():
        messages.error(request, '该申请无法编辑')
        return redirect('leave_detail', pk)
    
    if request.method == 'POST':
        form = LeaveApplicationForm(request.POST, request.FILES, instance=application)
        if form.is_valid():
            application = form.save()
            
            # 根据提交的动作决定状态
            action = request.POST.get('action', 'save_draft')
            if action == 'submit':
                try:
                    LeaveApprovalService.submit_application(application, request.user)
                    messages.success(request, '请假申请已成功提交！')
                except Exception as e:
                    messages.error(request, f'提交失败：{str(e)}')
            else:
                messages.success(request, '修改已保存！')
            
            return redirect('leave_detail', application.id)
    else:
        form = LeaveApplicationForm(instance=application)
    
    # 获取用户的请假余额
    leave_balances = []
    for leave_type in LeaveType.objects.filter(is_active=True):
        balance = LeaveBalanceService.get_user_balance(request.user, leave_type)
        leave_balances.append(balance)
    
    context = {
        'form': form,
        'application': application,
        'leave_balances': leave_balances,
    }
    
    return render(request, 'leaves/apply_leave.html', context)


@login_required
def my_leaves(request):
    """我的请假申请"""
    applications = LeaveApplication.objects.filter(applicant=request.user)
    
    # 筛选
    filter_form = LeaveFilterForm(request.GET)
    if filter_form.is_valid():
        if filter_form.cleaned_data['status']:
            applications = applications.filter(status=filter_form.cleaned_data['status'])
        if filter_form.cleaned_data['leave_type']:
            applications = applications.filter(leave_type=filter_form.cleaned_data['leave_type'])
        if filter_form.cleaned_data['start_date']:
            applications = applications.filter(start_date__gte=filter_form.cleaned_data['start_date'])
        if filter_form.cleaned_data['end_date']:
            applications = applications.filter(end_date__lte=filter_form.cleaned_data['end_date'])
    
    applications = applications.order_by('-created_at')
    
    # 分页
    paginator = Paginator(applications, 10)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'title': '我的申请',
        'applications': page_obj,
        'page_obj': page_obj,
        'is_paginated': page_obj.has_other_pages(),
        'leave_types': LeaveType.objects.filter(is_active=True),
        'show_apply_button': True,
        'show_applicant': False,
    }
    
    return render(request, 'leaves/leave_list.html', context)


@login_required
@role_required(['hr', 'admin'])
def all_leaves(request):
    """所有请假申请（HR和管理员）"""
    applications = LeaveApplication.objects.all()
    
    # 筛选
    filter_form = LeaveFilterForm(request.GET)
    if filter_form.is_valid():
        if filter_form.cleaned_data['status']:
            applications = applications.filter(status=filter_form.cleaned_data['status'])
        if filter_form.cleaned_data['leave_type']:
            applications = applications.filter(leave_type=filter_form.cleaned_data['leave_type'])
        if filter_form.cleaned_data['start_date']:
            applications = applications.filter(start_date__gte=filter_form.cleaned_data['start_date'])
        if filter_form.cleaned_data['end_date']:
            applications = applications.filter(end_date__lte=filter_form.cleaned_data['end_date'])
    
    applications = applications.order_by('-created_at')
    
    # 分页
    paginator = Paginator(applications, 15)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'title': '所有申请',
        'applications': page_obj,
        'page_obj': page_obj,
        'is_paginated': page_obj.has_other_pages(),
        'leave_types': LeaveType.objects.filter(is_active=True),
        'show_apply_button': False,
        'show_applicant': True,
    }
    
    return render(request, 'leaves/leave_list.html', context)


@login_required
def leave_detail(request, pk):
    """请假申请详情"""
    application = get_object_or_404(LeaveApplication, pk=pk)
    
    # 权限检查：只有申请人、审批人或HR/管理员可以查看
    can_view = (
        application.applicant == request.user or
        LeaveApprovalService.can_user_approve(request.user, application) or
        request.user.userprofile.role in ['hr', 'admin']
    )
    
    if not can_view:
        return HttpResponseForbidden('您没有权限查看此申请')
    
    # 检查是否可以审批
    can_approve = LeaveApprovalService.can_user_approve(request.user, application)
    
    # 获取审批记录
    approval_records = application.approval_records.all().order_by('-created_at')
    
    context = {
        'application': application,
        'can_approve': can_approve,
        'approval_records': approval_records,
    }
    
    return render(request, 'leaves/leave_detail.html', context)


@login_required
def approval_list(request):
    """待审批列表"""
    if not hasattr(request.user, 'userprofile') or not request.user.userprofile.can_approve_leave():
        messages.error(request, '您没有审批权限')
        return redirect('dashboard')
    
    pending_applications = LeaveApprovalService.get_pending_approvals(request.user)
    
    # 分页
    paginator = Paginator(pending_applications, 10)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'title': '待审批申请',
        'applications': page_obj,
        'page_obj': page_obj,
        'is_paginated': page_obj.has_other_pages(),
        'leave_types': LeaveType.objects.filter(is_active=True),
        'show_apply_button': False,
        'show_applicant': True,
    }
    
    return render(request, 'leaves/leave_list.html', context)


@login_required
def approve_leave(request, pk):
    """审批请假申请"""
    application = get_object_or_404(LeaveApplication, pk=pk)
    
    if not LeaveApprovalService.can_user_approve(request.user, application):
        return HttpResponseForbidden('您没有权限审批此申请')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        comments = request.POST.get('comments', '')
        
        try:
            if action == 'approve':
                LeaveApprovalService.approve_application(application, request.user, comments)
                messages.success(request, '申请已批准')
            elif action == 'reject':
                LeaveApprovalService.reject_application(application, request.user, comments)
                messages.success(request, '申请已拒绝')
            elif action == 'return':
                LeaveApprovalService.return_application(application, request.user, comments)
                messages.success(request, '申请已退回')
            
            return redirect('leave_detail', pk)
        except Exception as e:
            messages.error(request, f'操作失败：{str(e)}')
    
    context = {
        'application': application,
    }
    
    return render(request, 'leaves/approval_form.html', context)


@login_required
@require_POST
def cancel_leave(request, pk):
    """取消请假申请"""
    application = get_object_or_404(LeaveApplication, pk=pk, applicant=request.user)
    
    try:
        LeaveApprovalService.cancel_application(application, request.user)
        messages.success(request, '申请已取消')
    except Exception as e:
        messages.error(request, f'取消失败：{str(e)}')
    
    return redirect('leave_detail', pk)


@login_required
def profile(request):
    """个人资料"""
    user_profile, created = UserProfile.objects.get_or_create(user=request.user)
    
    if request.method == 'POST':
        user_form = UserUpdateForm(request.POST, instance=request.user)
        profile_form = UserProfileForm(request.POST, instance=user_profile)
        
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, '个人资料已更新')
            return redirect('profile')
    else:
        user_form = UserUpdateForm(instance=request.user)
        profile_form = UserProfileForm(instance=user_profile)
    
    # 获取请假统计
    leave_summary = LeaveStatistics.get_user_leave_summary(request.user)

    context = {
        'user_form': user_form,
        'profile_form': profile_form,
        'leave_summary': leave_summary,
    }
    
    return render(request, 'leaves/profile.html', context)


def register(request):
    """用户注册"""
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            # 创建用户配置文件
            # UserProfile.objects.create(user=user)
            # messages.success(request, '注册成功！请登录您的账户。')
            return redirect('login')
    else:
        form = CustomUserCreationForm()

    context = {
        'form': form,
    }

    return render(request, 'registration/register.html', context)
# API视图（可选，用于AJAX请求）
@login_required
def api_leave_balance(request):
    """获取请假余额API"""
    leave_type_id = request.GET.get('leave_type_id')
    if not leave_type_id:
        return JsonResponse({'error': '缺少请假类型参数'}, status=400)
    
    try:
        leave_type = LeaveType.objects.get(id=leave_type_id)
        balance = LeaveBalanceService.get_user_balance(request.user, leave_type)
        
        return JsonResponse({
            'total_days': balance.total_days,
            'used_days': balance.used_days,
            'remaining_days': balance.remaining_days,
        })
    except LeaveType.DoesNotExist:
        return JsonResponse({'error': '请假类型不存在'}, status=404)


@login_required
def api_calculate_days(request):
    """计算请假天数API"""
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    
    if not start_date or not end_date:
        return JsonResponse({'error': '缺少日期参数'}, status=400)
    
    try:
        from datetime import datetime
        from .utils import WorkdayCalculator
        
        start = datetime.strptime(start_date, '%Y-%m-%d').date()
        end = datetime.strptime(end_date, '%Y-%m-%d').date()
        
        if start > end:
            return JsonResponse({'error': '开始日期不能晚于结束日期'}, status=400)
        
        workdays = WorkdayCalculator.calculate_workdays(start, end)
        
        return JsonResponse({
            'workdays': workdays,
            'total_days': (end - start).days + 1,
        })
    except ValueError:
        return JsonResponse({'error': '日期格式错误'}, status=400)


@login_required
@role_required(['hr', 'admin'])
def assign_role(request, user_id):
    """分配用户角色"""
    target_user = get_object_or_404(User, id=user_id)
    user_profile, created = UserProfile.objects.get_or_create(user=target_user)

    # 防止用户修改自己的角色（除非是超级管理员）
    if target_user == request.user and not request.user.is_superuser:
        messages.error(request, '您不能修改自己的角色')
        return redirect('user_management')

    if request.method == 'POST':
        form = UserRoleForm(request.POST, instance=user_profile)
        if form.is_valid():
            form.save()
            messages.success(request, f'已成功更新 {target_user.get_full_name() or target_user.username} 的角色信息')
            return redirect('user_management')
    else:
        form = UserRoleForm(instance=user_profile)

    context = {
        'form': form,
        'target_user': target_user,
        'user_profile': user_profile,
    }

    return render(request, 'leaves/assign_role.html', context)


@login_required
@role_required(['hr', 'admin'])
def user_management(request):
    """用户管理页面"""
    users = User.objects.select_related('userprofile').all()

    # 搜索和筛选
    search_form = UserSearchForm(request.GET)
    if search_form.is_valid():
        search_query = search_form.cleaned_data.get('search')
        role_filter = search_form.cleaned_data.get('role')
        department_filter = search_form.cleaned_data.get('department')

        if search_query:
            users = users.filter(
                Q(username__icontains=search_query) |
                Q(first_name__icontains=search_query) |
                Q(last_name__icontains=search_query) |
                Q(userprofile__employee_id__icontains=search_query)
            )

        if role_filter:
            users = users.filter(userprofile__role=role_filter)

        if department_filter:
            users = users.filter(userprofile__department=department_filter)

    users = users.order_by('userprofile__employee_id')

    # 分页
    paginator = Paginator(users, 15)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    context = {
        'users': page_obj,
        'page_obj': page_obj,
        'is_paginated': page_obj.has_other_pages(),
        'search_form': search_form,
    }

    return render(request, 'leaves/user_management.html', context)